package com.onesports.intelligent.k12.polarlight.controller.common;

import cn.gjing.tools.aliyun.oss.SimpleOssUpload;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.OSSObject;
import com.onesports.framework.kit.common.util.ParamUtils;
import com.onesports.framework.kit.common.util.TimeUtils;
import com.onesports.framework.kit.common.valid.Json;
import com.onesports.intelligent.k12.polarlight.common.errors.exceptions.BusinessException;
import com.onesports.intelligent.k12.polarlight.common.utils.ResultUtil;
import com.onesports.intelligent.k12.polarlight.domain.dto.common.IdDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.sys.AttachmentFileDTO;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.BizAttachmentFile;
import com.onesports.intelligent.k12.polarlight.service.sys.BizAttachmentFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Api(tags = "文件通用API")
@RestController("FileController")
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileController {

    @Value("${tools.aliyun.oss.expire-date: '2078-12-31 00:00:00'}")
    private String expireDate;

    private final SimpleOssUpload simpleUpload;

    private final BizAttachmentFileService bizAttachmentFileService;

    @PostMapping("/upload")
    @ApiOperation("文件上传(自动获取文件名)")
    public ResponseEntity<Map<String, String>> uploadFiles(List<MultipartFile> file) {
        Map<String, String> result = new HashMap<>();
        for (MultipartFile multipartFile : file) {
            String filename = multipartFile.getOriginalFilename();
            String ext = FilenameUtils.getExtension(filename);
            if(StringUtils.isNotBlank(ext)){
                ext= "."+ext;
            }
            String randomFileName = UUID.randomUUID().toString().replace("-", "")+ext;
            this.simpleUpload.upload(multipartFile, randomFileName);
            result.put(filename, randomFileName);
        }
        return ResponseEntity.ok(result);
    }

    @PostMapping("/upload-attachment")
    @ApiOperation("上传附件")
    public ResponseEntity<Map<String, String>> uploadAttachmentFiles(@Json AttachmentFileDTO dto) {
        Map<String, String> result = new HashMap<>();
        List<BizAttachmentFile> attachmentFiles = Lists.newArrayList();
        for (MultipartFile multipartFile : dto.getFile()) {
            String filename = multipartFile.getOriginalFilename();
            String ext = FilenameUtils.getExtension(filename);
            if(StringUtils.isNotBlank(ext)){
                ext= "."+ext;
            }
            String randomFileName = UUID.randomUUID().toString().replace("-", "")+ext;
            BizAttachmentFile attachmentFile = new BizAttachmentFile();
//            attachmentFile.setBizId(dto.getBizId());
//            attachmentFile.setBizType(dto.getBizType());
            attachmentFile.setBucket(simpleUpload.getOssMeta().getBucket());
            attachmentFile.setContentType(multipartFile.getContentType());
            attachmentFile.setOriginalFileName(filename);
            attachmentFile.setExtension(ext);
            attachmentFile.setSize(multipartFile.getSize());
            attachmentFile.setFileName(this.simpleUpload.upload(multipartFile, randomFileName));
            attachmentFile.setPath(randomFileName);
            attachmentFiles.add(attachmentFile);
            result.put(filename, randomFileName);

        }
        if(CollectionUtils.isNotEmpty(attachmentFiles)){
            bizAttachmentFileService.saveForCache(attachmentFiles);
        }
        return ResponseEntity.ok(result);
    }

    @PostMapping("/remove-attachment")
    @ApiOperation("删除附件")
    public ResponseEntity removeAttachment(@RequestBody IdDTO dto){
        BizAttachmentFile attachmentFile = bizAttachmentFileService.getById(dto.getId());
        simpleUpload.deleteFile(attachmentFile.getFileName());
        bizAttachmentFileService.removeById(dto.getId());
        return ResultUtil.success();
    }

    @GetMapping("/download")
    @ApiOperation("下载文件")
    public void fileDownload(String fileName, HttpServletResponse response) {
        if (ParamUtils.isEmpty(fileName)) {
            throw new BusinessException("请输入文件名称");
        }
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(simpleUpload.getOssMeta().getEndPoint(), simpleUpload.getOssMeta().getAccessKey(), simpleUpload.getOssMeta().getAccessKeySecret());
        OSSObject ossObject = this.toDownLoad(fileName, ossClient);
        if (ossObject != null) {
            InputStream inputStream = ossObject.getObjectContent();
            int buffer = 1024 * 10;
            byte data[] = new byte[buffer];
            boolean isError = false;
            try {
                response.setContentType("application/octet-stream");
                //将文件名转为ASCLL编码
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                int read;
                while ((read = inputStream.read(data)) != -1) {
                    response.getOutputStream().write(data, 0, read);
                }
                response.getOutputStream().flush();
                response.getOutputStream().close();
                ossObject.close();
            } catch (IOException e) {
                e.printStackTrace();
                isError = true;
            }
            if (isError) {
                throw new BusinessException("文件下载异常");
            }
        }
        ossClient.shutdown();
    }

    private OSSObject toDownLoad(String fileName, OSS ossClient) {
        // 生成签名URL。
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(simpleUpload.getOssMeta().getBucket(), fileName, HttpMethod.GET);
        //设置过期时间
        request.setExpiration(TimeUtils.toDate2(expireDate));
        // 通过HTTP GET请求生成签名URL。
        URL signedUrl = ossClient.generatePresignedUrl(request);
        // 使用签名URL发送请求。
        Map<String, String> customHeaders = new HashMap<>();
        // 添加GetObject请求头。
        return ossClient.getObject(signedUrl, customHeaders);
    }
}
